/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ie.tcd.cs.railtickets.server.dao.impl;

import ie.tcd.cs.railtickets.server.dao.SeatStateDAO;
import ie.tcd.cs.railtickets.server.domain.Route;
import ie.tcd.cs.railtickets.server.domain.RouteStation;
import ie.tcd.cs.railtickets.server.domain.RouteTime;
import ie.tcd.cs.railtickets.server.domain.SeatState;
import java.util.Date;
import java.util.Iterator;
import static ie.tcd.cs.railtickets.server.dao.impl.HibernateSessionFactory.getSession;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author Wenbo Sun
 */
public class SeatStateDAOImpl extends AbstractBaseDAOImpl implements SeatStateDAO {

    private static final Log log = LogFactory.getLog(SeatStateDAOImpl.class);

    public SeatState findBy(RouteTime routeTime, Date travelDate, RouteStation routeStation) {
        String query = "from SeatState seatState where seatState.travelTime = ? and "
                + "seatState.travelDate = ? and seatState.routeStation = ?";
        SeatState seatState = (SeatState) getSession().createQuery(query).setParameter(0, routeTime).setParameter(1, travelDate).setParameter(2, routeStation).uniqueResult();
        log.debug("seat available: " + seatState.getSeatAvail());
        return seatState;
    }

    public void bookOrCancel(SeatState seatState, int op) {
        SeatState seat = (SeatState) this.findById(SeatState.class, seatState.getId());
        seat.setSeatAvail(seat.getSeatAvail() + op);
//        getSession().update(seat);
        update(seatState);
    }

    public void bookOrCancel(List<SeatState> seatStates, int op) {
        for (SeatState seatState : seatStates) {
            bookOrCancel(seatState, op);
        }
    }

    public int findAvailable(RouteTime routeTime, Date travelDate, int... stationSequence) {
        String query = "select min(seatState.seatAvail) from SeatState seatState where seatState.travelTime = ? and " 
                + "seatState.travelDate = ? and seatState.routeStation.sequenceNum >= ? and "
                + "seatState.routeStation.sequenceNum < ?";
        Object o = getSession().createQuery(query).setParameter(0, routeTime)
                .setParameter(1, travelDate).setParameter(2, stationSequence[0])
                .setParameter(3, stationSequence[1]).uniqueResult();
        if (o == null)
            return -1;
        return (Integer) o;
    }

    public SeatState create(RouteTime routeTime, Date travelDate, RouteStation routeStation) {
        String query = "select routeStation.route from RouteStation routeStation where routeStation = ?";
        Route route = (Route) getSession().createQuery(query).setParameter(0, routeStation).uniqueResult();
        SeatState seatState = new SeatState(travelDate, routeTime, routeStation, route.getSeat());
        seatState.setId((Long) getSession().save(seatState));
        log.debug("create new seat state");
        return seatState;
    }

    public boolean isExist(RouteTime routeTime, Date travelDate, RouteStation routeStation) {
        String query = "from SeatState seatState where seatState.travelTime = ? and "
                + "seatState.travelDate = ? and seatState.routeStation = ?";
        boolean result = getSession().createQuery(query).setParameter(0, routeTime).setParameter(1, travelDate).setParameter(2, routeStation).iterate().hasNext();
        return result;
    }

}
